package com.rbw.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.rb.util.AppTextUtil;
import com.rb.util.EncodeUtil;
import com.rb.util.RandomUtil;
import com.rb.util.StringUtil;
import com.rb.util.sms.SMSInterface;
import com.rbw.cache.dao.UserCacheDao;
import com.rbw.constants.StringConstants;
import com.rbw.controller.res.ListResult;
import com.rbw.model.FavoriteBean;
import com.rbw.model.TechBean;
import com.rbw.model.UserBean;
import com.rbw.model.UserRequireBean;
import com.rbw.persist.dao.TechDao;
import com.rbw.persist.dao.UserDao;
import com.rbw.persist.dao.UserRequireDao;
import com.rbw.service.UserService;
import com.rbw.service.exception.ServiceException;

/**
 * 用户业务处理
 * 
 * @author cuihaidong
 *
 */
@Service
public class UserServiceImpl implements UserService {
	@Autowired
	UserDao userImpl;
	
	@Autowired
	TechDao techImpl;

	@Autowired
	UserCacheDao userCacheImpl;

	@Autowired
	UserRequireDao userRequireImpl;
	

    @Autowired
    SMSInterface smsClient;

	private Logger logger = Logger.getLogger(UserServiceImpl.class);

	@Override
	public UserBean existUser(int type, String username) {
		UserBean user = null;
		if (type == 1) {// 检查手机号
			user = userImpl.selectOneByPhone(username);
		} else if (type == 2) {// 检查电子邮箱
			user = userImpl.selectOneByEmail(username);
		}
		return user;
	}

	@Override
	public UserBean login(String sessionId, String username, String password) {
		UserBean user = userImpl.selectOneByPhone(username);
		if (user == null) {
			user = userImpl.selectOneByEmail(username);
		}

		if (user == null) {
			throw new ServiceException("object_is_not_exist", "用户");
		}
		password = EncodeUtil.sha256Hex(password);
		// 密码不正确
		if (!password.equals(user.getPassword())) {
			throw new ServiceException("user_password_is_error");
		}

		userCacheImpl.setUserSession(sessionId, user.getUid());
		return user;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public UserBean regByPhone(String sessionId, String phoneNum, String pwd, String spwd, String vcode) {
		String code = userCacheImpl.getVCode(phoneNum);
		if (code == null) {// 验证码已经失效
			throw new ServiceException("user_vcode_is_expire");
		}

		logger.info("phone is:" + phoneNum + ", vcode is:" + vcode + ", code = " + code);

		if (!vcode.equals(code)) {// 验证码输入有误
			throw new ServiceException("user_vcode_is_error");
		}
		// 用户是否存在
		if (existUser(1, phoneNum) != null) {// 存在
			throw new ServiceException("object_is_exist", "用户");
		}

		// 密码不一致
		if (!pwd.equals(spwd)) {
			throw new ServiceException("user_password_is_not_same");
		}


		// 不存在
		UserBean user = new UserBean();
		user.setUid(AppTextUtil.getPrimaryKey());
		user.setPhoneNum(phoneNum);
		user.setPassword(EncodeUtil.sha256Hex(pwd));

		// 写入数据库
		boolean flag = userImpl.insert(user) == 1;
		if (flag) {// 新增用户
			userCacheImpl.setUserSession(sessionId, user.getUid());
			// 插入日志信息
			return user;
		}
		return null;
	}
	@Transactional(rollbackFor = Exception.class)
	@Override
	public UserBean regByEmail(String sessionId, String email, String pwd, String spwd, String vcode) {
		String code = userCacheImpl.getVCode(email);
		if (code == null) {// 验证码已经失效
			throw new ServiceException("user_vcode_is_expire");
		}
		if (!vcode.equals(code)) {// 验证码输入有误
			throw new ServiceException("user_vcode_is_error");
		}
		// 用户是否存在
		if (existUser(1, email) != null) {// 存在
			throw new ServiceException("object_is_exist", "用户");
		}

		// 密码不一致
		if (!pwd.equals(spwd)) {
			throw new ServiceException("user_password_is_not_same");
		}

		// 不存在
		UserBean user = new UserBean();
		user.setUid(AppTextUtil.getPrimaryKey());
		user.setEmail(email);
		user.setPassword(EncodeUtil.sha256Hex(pwd));

		// 写入数据库
		boolean flag = userImpl.insert(user) == 1;
		if (flag) {// 新增用户
			userCacheImpl.setUserSession(sessionId, user.getUid());
			// 插入日志信息
			return user;
		}
		return null;
	}

	@Override
	public boolean sendVCode(int action, int type, String username) {
		if (action == 1) {// 注册
			UserBean user = existUser(type, username);
			if (user != null) {// 用户已经注册
				throw new ServiceException("object_is_exist", type == 1 ? "手机号" : "邮箱");
			}

			// 通过手机发送验证码
			if (type == 1) {
				sendVCodeByPhone(username, "vcode_message_reg_tip");
			} else {
				sendVCodeByEmail(username);
			}

			return true;
		}

		if (action == 2) {// 找回密码
			UserBean user = existUser(type, username);
			if (user == null) {// 用户未注册
				throw new ServiceException("object_is_not_exist", type == 1 ? "手机号" : "邮箱");
			}
			// 通过手机发送验证码
			if (type == 1) {
				sendVCodeByPhone(username, "vcode_message_resetPwd_tip");
			} else {
				sendVCodeByEmail(username);
			}

			return true;
		}

		if (action == 3) {// 绑定
			UserBean user = existUser(type, username);
			if (user != null) {// 用户已经注册
				throw new ServiceException("object_is_exist", type == 1 ? "手机号" : "邮箱");
			}

			if (type == 1) {
				// 通过手机发送验证码
				sendVCodeByPhone(username, "vcode_message_bind_tip");
			} else {
				sendVCodeByEmail(username);
			}

			return true;
		}

		return false;
	}

	@Override
	public UserBean existUser(String sessionId) {
		String uid = userCacheImpl.getUidBySession(sessionId);
		if (uid == null)
			return null;
		return userImpl.selectOne(uid);
	}

	/**
	 * 发送验证码
	 * 
	 * @param phone
	 * @return
	 */
	private String sendVCodeByPhone(String phone, String type) {

		String code = userCacheImpl.getVCode(phone);
		// 如果没有则新生成 如果已有则发送之前生成的。
		String vcode = code == null ? RandomUtil.getRandomNum(4) : code;
		// TODO:短信接口
	    String msg = StringConstants.getInstance().getString(type, vcode);
        boolean flag = smsClient.send(phone, msg);
        if (flag) {
        	userCacheImpl.setVCode(phone, vcode);
        }
		logger.info("send phone is:" + phone + ", vcode is:" + vcode);
		return vcode;
	}

	private String sendVCodeByEmail(String email) {
		String code = userCacheImpl.getVCode(email);
		// 如果没有则新生成 如果已有则发送之前生成的。
		String vcode = code == null ? RandomUtil.getRandomCharAndNum(6) : code;
		logger.info("send phone is:" + email + ", vcode is:" + vcode);
		// TODO:邮箱接口
		userCacheImpl.setVCode(email, vcode);
		return vcode;
	}

	@Override
	public boolean editUser(HttpServletRequest request, int type, String value, String vcode) {
		UserBean user = (UserBean) request.getAttribute("user");
		boolean flag = false;
		if (type == 1) {
			user.setName(value);
		} else {
			String code = userCacheImpl.getVCode(value);
			if (code == null) {// 验证码已经失效
				throw new ServiceException("user_vcode_is_expire");
			}
			if (!vcode.equals(code)) {// 验证码输入有误
				throw new ServiceException("user_vcode_is_error");
			}
			if (type == 2) {
				user.setPhoneNum(value);
			} else {
				user.setEmail(value);
			}
		}
		flag = userImpl.update(user) > 0;
		if (!flag) {
			throw new ServiceException("fail", "修改用户信息");
		}
		request.setAttribute("user", user);
		return flag;
	}

	@Override
	public boolean submitRequire(String username, String telephone, String require) {
		UserRequireBean userrequire = new UserRequireBean();
		userrequire.setRid(AppTextUtil.getPrimaryKey());
		userrequire.setUsername(username);
		userrequire.setTelephone(telephone);
		userrequire.setContent(require);
		return userRequireImpl.insert(userrequire) > 0;
	}

	@Override
	public boolean resetPassword(HttpServletRequest request, String pwd, String newpwd, String snewpwd) {
		UserBean user = (UserBean) request.getAttribute("user");
		if(StringUtil.checkEmpty(pwd) || pwd.equals(newpwd) ){
			throw new ServiceException("new_password_is_same");
		}
		if(!user.getPassword().equals(EncodeUtil.sha256Hex(pwd))){
			throw new ServiceException("user_password_is_error");
		}
		if(StringUtil.checkEmpty(newpwd) || !newpwd.equals(snewpwd) ){
			throw new ServiceException("user_password_is_not_same");
		}
		String regex = "^[\\w]{6,12}$";  
		if(StringUtil.checkEmpty(newpwd) || !newpwd.matches(regex)){
			throw new ServiceException("user_password_is_error");
		}
		user.setPassword(EncodeUtil.sha256Hex(newpwd));
		boolean flag = userImpl.update(user) > 0;
		if (!flag) {
			throw new ServiceException("fail", "修改密码");
		}
		request.setAttribute("user", user);
		return flag;
	}

	@Override
	public boolean favorite(HttpServletRequest request, String targetId, int type) {
		UserBean user = (UserBean) request.getAttribute("user");
		if(user == null) {
			throw new ServiceException("session_fail");
		}
		String uid = user.getUid();
		FavoriteBean f = userImpl.selectFavoriteByUid(uid, targetId);
		if(f != null) {
			f.setState(f.getState()==1 ? 2 : 1);// 已收藏则取消收藏，未收藏则收藏
			return userImpl.updateFavorite(f) > 0;
		}
		f = new FavoriteBean();
		f.setState(1);
		f.setUserId(user.getUid());
		f.setTargetId(targetId);
		f.setType(type);
		return userImpl.insertFavorite(f) > 0;
	}

	@Override
	public ListResult<TechBean> getFavorites(String sessionId, int page, int pageSize) {
		ListResult<TechBean> result = new ListResult<>();
		String uid = userCacheImpl.getUidBySession(sessionId);
		Map<String, Object> params = new HashMap<>();
		int start = (page - 1) * pageSize;
		params.put("start", start);
		params.put("pageSize", pageSize);
		params.put("userId", uid);
		int totalSize = techImpl.selectUserFavoriteTotal(params);
		
		List<TechBean> beans = techImpl.selectUserFavoriteByPage(params);
		result.setData(beans);
		result.setTotalSize(totalSize);
		return result;
	}
}
